package
{
   import _debug.Stats;
   
   import com.bit101.components.PushButton;
   import com.greensock.TimelineMax;
   import com.greensock.TweenMax;
   import com.greensock.easing.Linear;
   import com.greensock.easing.Quint;
   import com.greensock.plugins.FramePlugin;
   import com.greensock.plugins.TweenPlugin;
   
   import flash.display.MovieClip;
   import flash.display.Sprite;
   import flash.display.StageAlign;
   import flash.display.StageScaleMode;
   import flash.events.Event;
   import flash.events.MouseEvent;
   import flash.geom.Point;
   import flash.utils.getDefinitionByName;
   
   import org.flintparticles.common.actions.Age;
   import org.flintparticles.common.actions.Fade;
   import org.flintparticles.common.counters.TimePeriod;
   import org.flintparticles.common.counters.ZeroCounter;
   import org.flintparticles.common.events.EmitterEvent;
   import org.flintparticles.common.initializers.ImageClass;
   import org.flintparticles.common.initializers.Lifetime;
   import org.flintparticles.common.initializers.ScaleImageInit;
   import org.flintparticles.twoD.actions.Accelerate;
   import org.flintparticles.twoD.actions.Move;
   import org.flintparticles.twoD.actions.RandomDrift;
   import org.flintparticles.twoD.emitters.Emitter2D;
   import org.flintparticles.twoD.initializers.Position;
   import org.flintparticles.twoD.initializers.Velocity;
   import org.flintparticles.twoD.renderers.DisplayObjectRenderer;
   import org.flintparticles.twoD.zones.DiscSectorZone;
   import org.flintparticles.twoD.zones.PointZone;
   
   public class StrokeParticleMain_1 extends MovieClip
   {
      // fla
      public var mc1:MovieClip; // light, BlendMode.ADD
      public function get mcEm1():MovieClip { return MovieClip(mc1.mcEm1); }
      public function get mcEm2():MovieClip { return MovieClip(mc1.mcEm2); }
      public function get mcEm3():MovieClip { return MovieClip(mc1.mcEm3); }
      public function get mcEm4():MovieClip { return MovieClip(mc1.mcEm4); }
      public var mc2:MovieClip; // showing mc
      
      // pool
      private var mcEmPool:Vector.<MovieClip>;
      
      // UI
      public var comPlay:PushButton;
      public var comToggle1:PushButton;
      
      // particle
      private var pCanvas:DisplayObjectRenderer;
      private var emPool:Vector.<Emitter2D>;
      private var counter1:TimePeriod = new TimePeriod(300, 1);
      private var counter2:ZeroCounter = new ZeroCounter();
      
      // debug
      private var dbgPool:Vector.<Sprite>;
      
      // cmd
      private var cmd:TimelineMax = new TimelineMax();
      
      public function StrokeParticleMain_1()
      {
         super();
         
         // gs
         TweenPlugin.activate([FramePlugin]);
         
         addEventListener(Event.ADDED_TO_STAGE, onAdd);
         addEventListener(Event.REMOVED_FROM_STAGE, onRemove);
      }
      
      // ################### protected ##################
      
      // #################### private ###################
      
      private function onAdd(e:Event):void
      {
         // basic
         stage.align = StageAlign.TOP_LEFT;
         stage.scaleMode = StageScaleMode.NO_SCALE;
         
         // particle
         initParticle();
         pCanvas.x = 0;
         pCanvas.y = 0;
         mc1.addChild(pCanvas);
         
         // uI
         initUI();
         
         // renderer
         addEventListener(Event.ENTER_FRAME, renderAll, false, 0, true);
         
         // benchmark
         var stat:Stats = new Stats();
         stat.x = 506;
         stat.y = 0;
         addChild(stat);
      }
      
      private function onRemove(e:Event):void
      {
         removeEventListener(Event.ENTER_FRAME, renderAll);
      }
      
      // ________________________________________________
      //                               play, reset effect
      
      private function playEffx():void
      {
         // stop cmd(TimelineMax)
         cmd.stop();
         cmd.kill();
         cmd = new TimelineMax({
            onStart:function()
            {
            },
            onUpdate:function()
            {
            },
            onComplete:function()
            {
            }
         });
         
         // [init]
         TweenMax.to(mc1, 0, {frame:2});
         TweenMax.to(mc2, 0, {frame:2});
         
         // [actions]
         cmd.insert(TweenMax.to(mc1, 3.0, {frame:90, ease:Linear.easeNone}), 0.0);
         cmd.insert(TweenMax.to(mc2, 1.1, {frame:35, ease:Linear.easeNone}), 1.3);
         
         cmd.play();
      }
      
      private function stopEffx():void
      {
         // stop cmd(TimelineMax)
         cmd.stop();
         cmd.kill();
         cmd = new TimelineMax({
            onStart:function()
            {
            },
            onUpdate:function()
            {
            },
            onComplete:function()
            {
            }
         });
         
         // [init]
         TweenMax.to(mc1, 0, {frame:2});
         TweenMax.to(mc2, 0, {frame:1});
         
         // particle
         for each (var em:Emitter2D in emPool) 
         {
            em.counter = counter2;
         }
         
         // [actions]
         
         cmd.play();
      }
      
      // ________________________________________________
      //                                           render
      
      private function renderAll(e:Event):void
      {
         mcEmPool = Vector.<MovieClip>([mcEm1, mcEm2, mcEm3, mcEm4]);
         
         for (var i:int = 0; i < mcEmPool.length; ++i)
         {
            var mc:MovieClip = MovieClip(mcEmPool[i]);
            
            dbgPool[i].graphics.clear();
            
            if (mc)
            {
               if (!emPool[i].counter.running) emPool[i].counter = counter1;
               emPool[i].x = mc.x - pCanvas.x;
               emPool[i].y = mc.y - pCanvas.y;
               emPool[i].start();
               
               // display path
               if (comToggle1.selected)
               {
                  dbgPool[i].graphics.lineStyle(2, 0xff0000);
                  dbgPool[i].graphics.moveTo(mc.x - 5, mc.y);
                  dbgPool[i].graphics.lineTo(mc.x + 5, mc.y);
                  dbgPool[i].graphics.moveTo(mc.x, mc.y - 5);
                  dbgPool[i].graphics.lineTo(mc.x, mc.y + 5);
               }
            }
            else
            {
               emPool[i].counter = counter2;
            }
         }
      }
      
      // ________________________________________________
      //                                               UI
      
      private function initUI():void
      {
         comPlay = new PushButton(this, 456, 124, 'play', 
            function(e:MouseEvent)
            {
               playEffx();
            }
         );
         
         comToggle1 = new PushButton(this, 456, 154, 'show emitter',
            function(e:MouseEvent)
            {
               if (comToggle1.selected)
               {
                  comToggle1.label = 'hide emitter';
               }
               else
               {
                  comToggle1.label = 'show emitter';
                  
                  for each (var dbg:Sprite in dbgPool) 
                  {
                     dbg.graphics.clear();
                  }
               }
            }
         );
         comToggle1.toggle = true;
         
         stopEffx();
      }
      
      // ________________________________________________
      //                                         particle
      
      private function initParticle():void
      {
         pCanvas = new DisplayObjectRenderer();
         var viewCls1:Class = getDefinitionByName('ParticleUnit1') as Class;
         
         mcEmPool = Vector.<MovieClip>([mcEm1, mcEm2, mcEm3, mcEm4]);
         
         emPool = new Vector.<Emitter2D>();
         dbgPool = new Vector.<Sprite>();
         for (var i:int = 0; i < mcEmPool.length; ++i) 
         {
            var em:Emitter2D = new Emitter2D();
            em.x = 0;
            em.y = 0;
            em.addInitializer(new ImageClass(viewCls1));
            em.addInitializer(new Lifetime(2.0, 3.0));
            em.addInitializer(new Velocity(new DiscSectorZone(new Point, 15, 5, 0, 2*Math.PI)));
            em.addInitializer(new Position(new PointZone(new Point())));
            em.addInitializer(new ScaleImageInit(0.2, 1.0));
            em.addAction(new Age(Quint.easeIn));
            em.addAction(new Move());
            em.addAction(new Fade(1.0, 0));
            em.addAction(new Accelerate(0, 10));
            em.addAction(new RandomDrift(5, 5));
            em.addEventListener(EmitterEvent.EMITTER_EMPTY, stopEmitter);
            
            pCanvas.addEmitter(em);
            
            emPool.push(em);
            
            // debug
            var dbg:Sprite = new Sprite();
            dbg.x = mc1.x;
            dbg.y = mc1.y;
            addChild(dbg);
            dbgPool.push(dbg);
         }
      }
      
      private function stopEmitter(e:EmitterEvent):void
      {
         var em:Emitter2D = Emitter2D(e.currentTarget);
         em.stop();
      }
      
      // --------------------- LINE ---------------------
      
   }
   
}